CC = gcc
CFLAGS = -nostdlib -nostartfiles -nodefaultlibs -Wall -Wextra -c -fno-leading-underscore -I$(ROOT)/$(INCLUDE_DIR) -O0

ASM = nasm
ASMFLAGS = -felf

LD = ld
LDFLAGS = -t -T linker.ld 
BINARY = --oformat binary

ROOT = /home/elias/eliax/src

KERNEL_DIR = kernel
INCLUDE_DIR = include
DEV_DIR = dev
BOOT_DIR = boot
MM_DIR = mm
ASM_DIR = asm
LIB_DIR = lib

KERNEL_OBJS = k_init.o dev.o interrupts.o proc.o descriptors.o
DEV_OBJS = kbd.o vga.o pic.o timer.o fd.o
MM_OBJS = mm.o kheap.o virt_mm.o phys_mm.o
ASM_OBJS = asm.o isr_stubs.o mm_asm.o
LIB_OBJS = stdio.o math.o string.o

INCLUDE = $(INCLUDE_DIR)/*

START = -e _cr0

OUTPUT = eliax

eliax : kernel.img boot.o
	dd bs=512 count=1 if=boot.o of=$(OUTPUT)
	dd bs=512 count=120 seek=1 if=kernel.img of=$(OUTPUT)
	
#	nasm -o filler.o filler.s
#	dd bs=512 count=1 seek=26 if=filler.o of=eliax

	nm -n kernel.elf > syms
	rm *.o

kernel.img : $(ASM_OBJS) $(KERNEL_OBJS) $(DEV_OBJS) $(MM_OBJS) $(LIB_OBJS) cr0.o cr1.o
	$(LD) $(LDFLAGS) $(START) $(BINARY) -o kernel.img cr0.o cr1.o $(DEV_OBJS) $(MM_OBJS) \
	 $(KERNEL_OBJS) $(ASM_OBJS) $(LIB_OBJS)
	$(LD) $(LDFLAGS) $(START)  -o kernel.elf cr0.o cr1.o $(DEV_OBJS) $(MM_OBJS) \
	 $(KERNEL_OBJS) $(ASM_OBJS) $(LIB_OBJS)

# kernel code

k_init.o : $(KERNEL_DIR)/k_init.c 
	$(CC) $(CFLAGS) -o k_init.o $(KERNEL_DIR)/k_init.c 

descriptors.o : $(KERNEL_DIR)/descriptors.c $(INCLUDE_DIR)/descriptors.h 
	$(CC) $(CFLAGS) -o descriptors.o $(KERNEL_DIR)/descriptors.c 

dev.o : $(KERNEL_DIR)/dev.c $(INCLUDE_DIR)/dev.h 
	$(CC) $(CFLAGS) -o dev.o $(KERNEL_DIR)/dev.c 

interrupts.o : $(KERNEL_DIR)/interrupts.c $(INCLUDE_DIR)/interrupts.h
	$(CC) $(CFLAGS) -o interrupts.o $(KERNEL_DIR)/interrupts.c

proc.o : $(KERNEL_DIR)/proc.c $(INCLUDE_DIR)/proc.h 
	$(CC) $(CFLAGS) -o proc.o $(KERNEL_DIR)/proc.c 

# device code

kbd.o : $(DEV_DIR)/kbd.c $(INCLUDE_DIR)/kbd.h
	$(CC) $(CFLAGS) -o kbd.o $(DEV_DIR)/kbd.c

vga.o : $(DEV_DIR)/vga.c $(INCLUDE_DIR)/vga.h $(INCLUDE_DIR)/math.h
	$(CC) $(CFLAGS) -o vga.o $(DEV_DIR)/vga.c

pic.o : $(DEV_DIR)/pic.c $(INCLUDE_DIR)/pic.h
	$(CC) $(CFLAGS) -o pic.o $(DEV_DIR)/pic.c

timer.o : $(DEV_DIR)/timer.c $(INCLUDE_DIR)/timer.h
	$(CC) $(CFLAGS) -o timer.o $(DEV_DIR)/timer.c

fd.o : $(DEV_DIR)/fd.c $(INCLUDE_DIR)/fd.h
	$(CC) $(CFLAGS) -o fd.o $(DEV_DIR)/fd.c

# memory management code

mm.o : $(MM_DIR)/mm.c $(INCLUDE_DIR)/mm.h
	$(CC) $(CFLAGS) -o mm.o $(MM_DIR)/mm.c

virt_mm.o : $(MM_DIR)/virt_mm.c $(INCLUDE_DIR)/mm.h
	$(CC) $(CFLAGS) -o virt_mm.o $(MM_DIR)/virt_mm.c

phys_mm.o : $(MM_DIR)/phys_mm.c $(INCLUDE_DIR)/mm.h
	$(CC) $(CFLAGS) -o phys_mm.o $(MM_DIR)/phys_mm.c

kheap.o : $(MM_DIR)/kheap.c $(INCLUDE_DIR)/kheap.h
	$(CC) $(CFLAGS) -o kheap.o $(MM_DIR)/kheap.c

# libraries code

stdio.o : $(LIB_DIR)/stdio.c $(INCLUDE_DIR)/stdio.h
	$(CC) $(CFLAGS) -o stdio.o $(LIB_DIR)/stdio.c

math.o : $(LIB_DIR)/math.c $(INCLUDE_DIR)/math.h
	$(CC) $(CFLAGS) -o math.o $(LIB_DIR)/math.c

string.o : $(LIB_DIR)/string.c $(INCLUDE_DIR)/string.h
	$(CC) $(CFLAGS) -o string.o $(LIB_DIR)/string.c

# assembly code

isr_stubs.o : $(ASM_DIR)/isr_stubs.s
	$(ASM) $(ASMFLAGS) -o isr_stubs.o $(ASM_DIR)/isr_stubs.s

asm.o : $(ASM_DIR)/asm.s
	$(ASM) $(ASMFLAGS) -o asm.o $(ASM_DIR)/asm.s

mm_asm.o : $(ASM_DIR)/mm.s
	$(ASM) $(ASMFLAGS) -o mm_asm.o $(ASM_DIR)/mm.s

# boot code

boot.o : $(BOOT_DIR)/boot.asm
	$(ASM) -o boot.o $(BOOT_DIR)/boot.asm

cr0.o : $(BOOT_DIR)/cr0.s
	$(ASM) $(ASMFLAGS) -o cr0.o $(BOOT_DIR)/cr0.s

cr1.o : $(BOOT_DIR)/cr1.s
	$(ASM) $(ASMFLAGS) -o cr1.o $(BOOT_DIR)/cr1.s

clean :
	rm kernel.img
	rm kernel.elf
	rm eliax
	rm syms
